<?php

namespace app\admin\common;

use think\facade\Request;
use think\Controller;

class Base extends Controller {
    protected function initialize(){
        $this->isLogin();
        //想要访问的菜单id
        $node = input('node');
        //检查访问权限
        if (!$this->checkAuth()){
            $this->error('没有权限',url('index/welcome'));
        }
        if (!empty($node)){
            $this->breadcrumbNav($node);
        }

        //允许上传的图片格式
        $img_ext = get_system_val('img_ext');
        if (!empty($img_ext)){
            $img_ext = array_filter(explode(',',$img_ext));
            foreach ($img_ext as $k => $v){
                $img_ext[$k] = 'image/' . $v;
            }
            $img_ext = implode(',',$img_ext);
        }

        $this->assign('img_ext',$img_ext);
        $this->assign('file_size',get_system_val('file_size') == 0 ? 999999999999 * 10 : intval(get_system_val('file_size') * 1024));
    }

    /**
     * 空操作
     */
    public function _empty(){
        return $this->error('空操作，返回上次访问的页面中…');
    }

    /**
     * 验证是否已登录
     */
    function isLogin(){
        if (session('u_id') == false){
            $this->redirect('admin/Login/index');
        }
    }

    /**
     * 检查访问权限
     * @return bool
     * @throws
     */
    public function checkAuth(){
        $result = false;
        $user = get_user_id();

        $controller = Request::controller();
        $action = Request::action();

        //当前操作
        $current_action = $controller . '/' . $action;

        $not_auth_controller = config('auth.NOT_AUTH_CONTROLLER');//无需权限认证控制器
        $not_auth_action = config('auth.NOT_AUTH_ACTION');//无需权限认证操作
        //超级管理员、首页、免验证控制器无需验证权限
        if ($user == 1 || in_array(strtolower($current_action),$not_auth_action) || in_array(strtolower($controller),$not_auth_controller)){
            $result = true;
        }else{
            $user_rule = db('user_role')
                ->alias('ur')
                ->join('role_rule rr','ur.role_id = rr.role_id','left')
                ->join('rule r','r.id = rr.rule_id','left')
                ->where('ur.user_id',$user)
                ->where('r.rule',$current_action)
                ->where('r.status',1)
                ->field('r.*')
                ->select();
            if ($user_rule){
                $result = true;
            }
        }
        return $result;
    }

    /**
     * 面包屑
     * @param $id
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    function breadcrumbNav($id){
        $all_node = db('rule')->select();
        $node_arr = [];
        foreach ($all_node as $k => $v){
            $node_arr[$v['id']] = $v;
        }
        $pid = $node_arr[$id]['pid'];
        if ($pid != 0){
            $breadcrumb_nav = $this->getParentNode($pid);
        }
        array_push($breadcrumb_nav,$node_arr[$id]);
        $last_breadcrumb_nav = array_column($breadcrumb_nav,'pid');
        array_multisort($last_breadcrumb_nav,SORT_ASC,$breadcrumb_nav);

        $this->assign('breadcrumb_nav',$breadcrumb_nav);
    }

    /**
     * 获得树形结构数组
     * @param string $table 数据库表名
     * @param string $field 筛选字段
     * @param int $value 筛选值
     * @param string $order_field 排序字段
     * @param string $sort 排序方式
     * @return array
     * @throws
     */
    function getTreeList($table,$field = 'status',$value = 1,$order_field = 'id',$sort = 'asc'){
        $list = db($table)
            ->where($field,$value)
            ->order($order_field,$sort)
            ->select();

        $tree_list = $this->getTree($list);
        return $tree_list;
    }

    /**
     * 转化为树形结构
     * @param $list
     * @param int $pid
     * @param string $item_prefix
     * @return array
     */
    function getTree($list,$pid=0,$item_prefix = '') {
        static $icon = array('│', '├', '└');
        static $nbsp = " ";
        static $arr = array();
        $number = 1;
        foreach ($list as $row) {
            if ($row['pid'] == $pid) {
                $brotherCount = 0;
                //判断当前有多少个兄弟分类
                foreach ($list as $r) {
                    if ($row['pid'] == $r['pid']) {
                        $brotherCount++;
                    }
                }
                if ($brotherCount > 0) {
                    $j = $k = '';
                    if ($number == $brotherCount) {
                        $j .= $icon[2];
                        $k = $item_prefix ? $nbsp : '';
                    } else {
                        $j .= $icon[1];
                        $k = $item_prefix ? $icon[0] : '';
                    }
                    $spacer = $item_prefix ? $item_prefix . $j : '';
                    $row['name'] = $spacer . $row['name'];
                    $arr[] = $row;
                    $number++;
                    $this->getTree($list, $row['id'], $item_prefix . $k . $nbsp);
                }
            }
        }
        return $arr;
    }

    /**
     * 获取所有父级
     * @param $pid
     * @param array $parent_arr
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    function getParentNode($pid,$parent_arr = []){
        static $level = 1;
        $is_parent = db('rule')->where('id',$pid)->find();
        $parent_arr[] = $is_parent;
        if ($is_parent['pid'] != 0){
            $level++;
            return $this->getParentNode($is_parent['pid'],$parent_arr);
        }
        return $parent_arr;
    }

    /**
     * 获取所有子级
     * @param int $pid 父id
     * @param string $table 表名，不带表前缀
     * @return array
     */
    function getAllChild($pid,$table){
        $data = db($table)->field('id')->where('pid',$pid)->select();
        $child_ids = [];
        foreach ($data as $v){
            $child_ids[] = $v['id'];
            $child_ids = array_merge($child_ids, $this->getAllChild($v['id'],$table));
        }
        return $child_ids;
    }


    /**
     * 获取列表数据
     * @param string $table 不带前缀的表名
     * @param array $condition 查询条件
     * @param string $sort_field 排序字段
     * @param string $sort 排序方式
     * @param int $page 页码
     * @param int $limit 每页显示条数
     * @return array count:总数 list：当前页数据
     */
    function getListData($table, $condition, $sort_field = 'sort', $sort = 'asc', $page = 1, $limit = 10){
        $count = db($table)
            ->where($condition)
            ->count();

        $list = db($table)
            ->where($condition)
            ->order($sort_field, $sort)
            ->page($page, $limit)
            ->select();

        return ['count' => $count, 'list' => $list];
    }

    /**
     * 公共修改记录状态值方法
     * @param string $table 不带表前缀的表名
     * @param string/int/array $id 要修改状态的id
     * @param int/string $field 要修改的字段名代号。1：status 2：is_recommended 3:is_hot
     * @param int/string $type 操作类型。1：是。0：否
     * @return bool
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    function changeRecordStatus($table,$id,$field,$type){
        switch ($field){
            case 1:
                $field = 'status';
                break;
            case 2:
                $field = 'is_recommended';
                break;
            case 3:
                $field = 'is_hot';
                break;
            default:
                $field = 'status';
                break;
        }

        $data[$field] = $type == 1 ? 1 : 0;
        $result = db($table)
            ->where('id','in',$id)
            ->update($data);
        if ($result){
            return true;
        }else{
            return false;
        }

    }

    /**
     * 公共软删除方法
     * @param string $table 不带表前缀的表名
     * @param string/int/array $id 要修改软删除状态的id
     * @param string $log_msg 日志消息
     * @return bool
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    function delRecord($table,$id,$log_msg){
        if (is_array($id)){
            $id = implode(',',$id);
        }
        $result = db($table)
            ->where('id','in',$id)
            ->update(['is_del'=>1]);

        if ($result){
            insert_system_log($log_msg . $id);
            return true;
        }else{
            return false;
        }
    }

    function handleSeoUrl($link,$table,$action,$id=''){
        if ($action == 'add'){
            $link_arr = db($table)->column('seo_link');
            if (in_array($link, $link_arr)) {
                //如果已经存在，则在尾部追加1-99的随机数，但仍有极小概率重复
                $link = $link . mt_rand(1, 99);
            }
        }else{
            $repeat = db($table)
                ->where('id', '<>', $id)
                ->where('seo_link', $link)
                ->find();
            if ($repeat) {
                $link = $link . mt_rand(1, 99);
            }
        }
        return $link;
    }


    /**
     * 图片上传方法
     * @param $file
     * @param $save_path
     * @return array|bool|string
     */
    function uploadsImg($file,$save_path){
        $size = intval(get_system_val('file_size'));
        //0为无限制，手动赋值一个足够大的数值
        if ($size == 0){
            $size = 9999999999 * 10;
        }
        $ext = get_system_val('img_ext');
        $config = [
            'size' => $size,//最大允许上传1M
            'ext' => $ext//允许上传的文件类型
        ];

        $file_name = $file->getInfo()['name'];
        $file_name = substr($file_name,0,strrpos($file_name,'.'));
        
        $info = $file->validate($config)->move($save_path);
        if ($info){
            return ['path' => '/' . $save_path . $info->getFilename(),'file_name' =>$file_name];
        }else{
            return false;
        }
    }

}